<template>
  <div class="lov-select">
    <a-input
      v-model:value="currentDisplayText"
      readonly
      :placeholder="placeholder"
      class="lov-input"
      @click="openDialog"
    >
      <template #suffix>
        <div class="lov-suffix-icons">
          <CloseCircleOutlined
            v-if="currentDisplayText"
            class="lov-clear-icon"
            @click.stop="handleClear"
          />
          <SearchOutlined class="lov-search-icon" @click.stop="openDialog" />
        </div>
      </template>
    </a-input>

    <a-modal
      v-model:open="visible"
      :title="lovConfig?.title || '选择'"
      :width="lovConfig?.dialogWidth ? lovConfig.dialogWidth + 'px' : '700px'"
      :footer="null"
    >
      <!-- 查询区 -->
      <a-form layout="inline" class="query-form">
        <a-form-item
          v-for="column in queryableColumns"
          :key="column.fieldName"
          :label="column.displayName"
        >
          <a-input
            v-model:value="queryParams[column.fieldName]"
            :placeholder="`请输入${column.displayName}`"
            @pressEnter="handleQuery"
            style="width: 180px"
          />
        </a-form-item>
        <a-form-item>
          <a-button type="primary" @click="handleQuery">
            <template #icon><SearchOutlined /></template>
            查询
          </a-button>
          <a-button style="margin-left: 8px" @click="handleReset">
            <template #icon><ReloadOutlined /></template>
            重置
          </a-button>
        </a-form-item>
      </a-form>

      <!-- 表格 -->
      <a-table
        :dataSource="tableData"
        :columns="tableColumns"
        :scroll="{ y: lovConfig?.dialogHeight || 400 }"
        :pagination="false"
        :loading="loading"
        :rowKey="(record: any) => record[lovConfig?.valueField || 'id']"
        @resizeColumn="handleResizeColumn"
        size="small"
        class="lov-table"
      >
        <template #bodyCell="{ column, record }">
          <div @dblclick="handleSelect(record)" style="cursor: pointer">
            {{ record[column.dataIndex] }}
          </div>
        </template>
      </a-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <a-pagination
          v-model:current="pagination.pageNum"
          v-model:pageSize="pagination.pageSize"
          :total="pagination.total"
          :showSizeChanger="true"
          :showTotal="(total: number) => `共 ${total} 条`"
          :pageSizeOptions="['5', '10', '20', '50']"
          @change="handlePageChange"
          @showSizeChange="handlePageSizeChange"
        />
      </div>

      <template #footer>
        <a-button @click="visible = false">取消</a-button>
      </template>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, watch } from 'vue'
import request from '@/utils/request'
import { message } from 'ant-design-vue'
import {
  SearchOutlined,
  CloseCircleOutlined,
  ReloadOutlined,
} from '@ant-design/icons-vue'

interface LovColumnConfig {
  displayName: string
  fieldName: string
  columnWidth: number
  visible: boolean
  queryable: boolean
  columnOrder: number
  queryOrder: number
}

interface LovConfig {
  id: number
  lovCode: string
  lovName: string
  lovDesc: string
  title: string
  titleField: string
  hintField: string
  dataSourceSql: string
  dataSourceType: string
  displayField: string
  valueField: string
  pageSize: number
  dialogHeight: number
  dialogWidth: number
  columnCount: number
  editable: boolean
  enabled: boolean
  columns: LovColumnConfig[]
}

const props = defineProps({
  code: { type: String, required: true },
  modelValue: [String, Number],
  displayText: { type: String, default: '' }, // 显示文本，可以从外部传入，避免查询
  placeholder: { type: String, default: '点击选择' },
  customQueryParams: { type: Object, default: () => ({}) }, // 自定义查询参数
  onQuery: { type: Function, default: null }, // 打开LOV时执行的查询方法，用于动态设置查询参数
})

const emit = defineEmits(['update:modelValue', 'update:displayText', 'change'])

const visible = ref(false)
const loading = ref(false)
const innerDisplayText = ref('')
const lovConfig = ref<LovConfig | null>(null)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const queryParams = ref<Record<string, any>>({})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const tableData = ref<any[]>([])
const pagination = ref({
  pageNum: 1,
  pageSize: 10,
  total: 0,
  pages: 0
})

// 计算最终显示的文本：优先使用外部传入的displayText，否则使用内部的
const currentDisplayText = computed({
  get: () => props.displayText || innerDisplayText.value,
  set: (val) => {
    innerDisplayText.value = val
    emit('update:displayText', val)
  }
})

// 计算可查询的列
const queryableColumns = computed(() => {
  if (!lovConfig.value?.columns) return []
  return lovConfig.value.columns
    .filter(col => col.queryable)
    .sort((a, b) => a.queryOrder - b.queryOrder)
})

// 计算可见的列
const visibleColumns = computed(() => {
  if (!lovConfig.value?.columns) return []
  return lovConfig.value.columns
    .filter(col => col.visible)
    .sort((a, b) => a.columnOrder - b.columnOrder)
})

// 转换为 Ant Design Table 的列格式
const tableColumns = computed(() => {
  return visibleColumns.value.map(col => ({
    title: col.displayName,
    dataIndex: col.fieldName,
    key: col.fieldName,
    width: col.columnWidth,
    resizable: true,
    ellipsis: true,
  }))
})

// 加载LOV配置
async function loadConfig() {
  try {
    const response = await request.get(`/lov/config/code/${props.code}`)
    lovConfig.value = response.data
    pagination.value.pageSize = lovConfig.value?.pageSize || 10
  } catch (error) {
    console.error('加载配置失败:', error)
    message.error('LOV配置加载失败')
  }
}

// 查询数据
async function loadData() {
  if (!lovConfig.value) return

  loading.value = true
  try {
    const response = await request.get(`/lov/query/${props.code}`, {
      params: {
        ...queryParams.value,
        pageNum: pagination.value.pageNum,
        pageSize: pagination.value.pageSize,
      }
    })

    const result = response.data
    tableData.value = result.list || []
    pagination.value.total = result.total || 0
    pagination.value.pages = result.pages || 0
  } catch (error) {
    console.error('加载数据失败:', error)
    tableData.value = []
    message.error('数据加载失败，请检查网络连接')
  } finally {
    loading.value = false
  }
}

// 打开对话框
async function openDialog() {
  if (!lovConfig.value) {
    await loadConfig()
  }

  // 如果配置了onQuery回调函数，执行它来动态设置查询参数
  if (props.onQuery && typeof props.onQuery === 'function') {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const params: Record<string, any> = {}

    // 创建事件对象，包含param属性供回调函数设置参数
    const event = {
      param: params
    }

    try {
      // 调用onQuery回调函数
      props.onQuery(event)

      // 如果设置了参数，使用自定义参数查询
      if (Object.keys(params).length > 0) {
        visible.value = true
        pagination.value.pageNum = 1
        await query(params, 1)
        return
      }
    } catch (error) {
      console.error('query回调执行失败:', error)
      message.error('查询参数设置失败')
      return
    }
  }

  // 默认行为：正常打开对话框
  visible.value = true
  pagination.value.pageNum = 1
  loadData()
}

// 查询按钮点击（重置到第1页）
function handleQuery() {
  pagination.value.pageNum = 1
  loadData()
}

// 页码变化（不重置页码，直接加载数据）
function handlePageChange() {
  loadData()
}

// 每页条数变化（重置到第1页）
function handlePageSizeChange() {
  pagination.value.pageNum = 1
  loadData()
}

// 重置
function handleReset() {
  queryParams.value = {}
  handleQuery()
}

// 选择行
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function handleSelect(row: any) {
  if (!lovConfig.value) return

  const valueField = lovConfig.value.valueField
  const displayField = lovConfig.value.displayField
  const value = row[valueField]
  const text = row[displayField]

  emit('update:modelValue', value)
  currentDisplayText.value = text
  // change事件返回完整的row对象，包含所有字段
  emit('change', row)
  visible.value = false
}

// 清空
function handleClear() {
  emit('update:modelValue', '')
  currentDisplayText.value = ''
  emit('change', null)
}

// 根据值加载显示文本（仅在没有外部传入displayText时调用）
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function loadDisplayText(value: any) {
  if (!value) {
    innerDisplayText.value = ''
    return
  }

  try {
    const response = await request.get(`/lov/display/${props.code}/${value}`)
    innerDisplayText.value = response.data || value
  } catch (error) {
    console.error('加载显示文本失败:', error)
    innerDisplayText.value = value
  }
}

// 程序化设置值和文本（用于级联赋值等场景）
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setValue(value: any, text?: string) {
  emit('update:modelValue', value)
  if (text !== undefined) {
    innerDisplayText.value = text
    emit('update:displayText', text)
  } else if (value) {
    // 如果没有提供text，则尝试加载
    loadDisplayText(value)
  } else {
    innerDisplayText.value = ''
    emit('update:displayText', '')
  }
}

// 使用自定义参数查询数据（支持MyBatis动态SQL）
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function query(customParams: Record<string, any>, pageNum: number = 1, pageSize?: number) {
  if (!lovConfig.value) {
    await loadConfig()
  }

  loading.value = true
  try {
    const response = await request.post(
      `/lov/query/${props.code}/custom`,
      customParams,
      {
        params: {
          pageNum: pageNum,
          pageSize: pageSize || pagination.value.pageSize,
        }
      }
    )

    const result = response.data
    tableData.value = result.list || []
    pagination.value.total = result.total || 0
    pagination.value.pages = result.pages || 0
    pagination.value.pageNum = pageNum
    if (pageSize) {
      pagination.value.pageSize = pageSize
    }

    return result
  } catch (error) {
    console.error('自定义查询失败:', error)
    tableData.value = []
    message.error('查询失败，请检查参数或网络连接')
    throw error
  } finally {
    loading.value = false
  }
}

// 打开对话框并使用自定义参数查询
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function openDialogWithCustomQuery(customParams: Record<string, any>) {
  if (!lovConfig.value) {
    await loadConfig()
  }
  visible.value = true
  pagination.value.pageNum = 1
  await query(customParams, 1)
}

// 列宽调整
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function handleResizeColumn(w: number, col: any) {
  col.width = w
}

// 监听modelValue变化（仅在没有外部传入displayText时才查询）
watch(() => props.modelValue, (newValue) => {
  // 如果外部已经传入了displayText，则不需要查询
  if (props.displayText) {
    return
  }

  // 否则根据值查询显示文本
  if (newValue) {
    loadDisplayText(newValue)
  } else {
    innerDisplayText.value = ''
  }
}, { immediate: true })

// 监听外部displayText变化
watch(() => props.displayText, (newText) => {
  if (newText !== undefined) {
    innerDisplayText.value = newText
  }
}, { immediate: true })

onMounted(async () => {
  await loadConfig()
  // 如果有modelValue但没有displayText，则查询显示文本
  if (props.modelValue && !props.displayText) {
    loadDisplayText(props.modelValue)
  }
})

// 暴露方法给父组件
defineExpose({
  query,
  openDialogWithCustomQuery,
  loadData,
  openDialog,
  setValue  // 暴露setValue方法供外部调用
})
</script>

<style scoped>
.lov-select {
  width: 100%;
}

.lov-input {
  cursor: pointer;
}

.lov-input :deep(.ant-input) {
  cursor: pointer;
}

.lov-suffix-icons {
  display: flex;
  align-items: center;
  gap: 8px;
}

.lov-clear-icon {
  font-size: 14px;
  color: rgba(0, 0, 0, 0.25);
  cursor: pointer;
  transition: color 0.3s;
}

.lov-clear-icon:hover {
  color: rgba(0, 0, 0, 0.45);
}

.lov-search-icon {
  font-size: 14px;
  color: #1890ff;
  cursor: pointer;
  transition: color 0.3s;
}

.lov-search-icon:hover {
  color: #40a9ff;
}

.query-form {
  margin-bottom: 16px;
}

.query-form :deep(.ant-form-item) {
  margin-bottom: 16px;
}

.lov-table {
  margin-bottom: 16px;
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
  padding-top: 16px;
}
</style>

